/*******************************************************************
 *
 * Copyright (C), 2021-2022, LS, All rights reserved.
 *
 * Author      : 
 * Create Time : 2020-12-17
 * Version     : v0.1
 * Description : 
 *******************************************************************/

/*----------------------------Head file----------------------------*/
#include "flash.h"
#include "sys_task.h"
#include "user_config.h"
#include "app_store_mem.h"
#include "bsp_hw_config.h"
#include "ls_ble_crc16.h"

#define APP_MEM_LOG_EN      1

#if APP_MEM_LOG_EN
#include "log.h"
#define APP_MEM_LOG         LOG_DEBUG
#else
#define APP_MEM_LOG(...)
#endif

/*----------------------------macro file---------------------------*/
#define FLASH_SECTOR_SIZE       0x1000
#define CRC_INIT_VALUE          0xFFFF
#define CHECK_VALID_MAX_TIMES   3

#define WDT_FEED()

#define hal_store_erase_sector  hal_flash_erase_sector
#define hal_store_write         hal_flash_write
#define hal_store_read          hal_flash_read

/*----------------------------type define--------------------------*/

/*----------------------------var define---------------------------*/
static uint8_t store_mem_err_cnt = 0;

static index_data_t skip_index = 
{
    //No need to save
    .index_start_addr = SKIP_INDEX_SAVED_START_ADDR,
    .index_end_addr = SKIP_INDEX_SAVED_END_ADDR,
    .data_start_addr = SKIP_DATA_SAVED_START_ADDR,
    .data_end_addr = SKIP_DATA_SAVED_END_ADDR,
    .cache_max_size = 100*sizeof(save_skip_packet_t), //22400 bytes, need (7 * 0x1000).
    .addr_valid = false,
    .data_size = sizeof(save_skip_packet_t),
    .tmp_addr = SKIP_DATA_SAVED_START_ADDR,

    //Need to save
    .index_addr = SKIP_INDEX_SAVED_START_ADDR,
    .latest_addr = SKIP_DATA_SAVED_START_ADDR,
    .oldest_addr = SKIP_DATA_SAVED_START_ADDR,
};

/*-------------------------func declarative------------------------*/

/*-----------------------------------------------------------------*/

static void app_store_mem_error_handle(void)
{
    if(store_mem_err_cnt < 2) {
        store_mem_err_cnt++;
    }
    else {
        store_mem_err_cnt = 0;
        sys_task_msg_send(MSG_TYPE_BG, BG_EVT_STORE_MEM_ERR_HDL);
    }
}

static bool update_index_addr(uint32_t locate_addr, index_data_t *s_addr)
{
    if(locate_addr < s_addr->index_start_addr || locate_addr > s_addr->index_end_addr) {
        APP_MEM_LOG("locate_index address error.\n");
        app_store_mem_error_handle();
        return false;
    }

    s_addr->index_addr = locate_addr;

    return true;
}

static bool update_latest_data_addr(uint32_t latest_addr, index_data_t *s_addr)
{
    if(latest_addr < s_addr->data_start_addr || latest_addr > s_addr->data_end_addr) {
        APP_MEM_LOG("latest_index address error: %x.\n", latest_addr);
        app_store_mem_error_handle();
        return false;
    }

    s_addr->latest_addr = latest_addr;

    return true;
}

static bool update_oldest_data_addr(uint32_t oldest_addr, index_data_t *s_addr, bool max_size_check)
{
    if(oldest_addr < s_addr->data_start_addr || oldest_addr > s_addr->data_end_addr) {
        APP_MEM_LOG("oldest_index address error: %x.\n", oldest_addr);
        app_store_mem_error_handle();
        return false;
    }

    if(max_size_check) {
        if((s_addr->latest_addr >= oldest_addr)) {
            if((s_addr->latest_addr - oldest_addr) >= s_addr->cache_max_size)
                s_addr->oldest_addr = s_addr->latest_addr - s_addr->cache_max_size;
            else
                s_addr->oldest_addr = oldest_addr;
            //APP_MEM_LOG("oldest_index address11: %x.\n", s_addr->oldest_addr);
        }
        else {
            if( ((s_addr->data_end_addr - oldest_addr) + (s_addr->latest_addr - s_addr->data_start_addr)) \
                    >= s_addr->cache_max_size)
            {
                if((s_addr->latest_addr - s_addr->data_start_addr) == s_addr->cache_max_size) {
                    s_addr->oldest_addr = s_addr->data_start_addr;
                }
                else {
                    uint32_t rest = (s_addr->data_end_addr - s_addr->data_start_addr) % s_addr->data_size;
                    s_addr->oldest_addr = (s_addr->data_end_addr - rest) - \
                        (s_addr->cache_max_size - (s_addr->latest_addr - s_addr->data_start_addr));
                }
                //APP_MEM_LOG("oldest_index address22: %x.\n", s_addr->oldest_addr);
            }
            else
                s_addr->oldest_addr = oldest_addr;
        }
    }
    else
        s_addr->oldest_addr = oldest_addr;

    return true;
}

static bool update_tmp_data_addr(uint32_t tmp_addr, index_data_t *s_addr)
{
    if(tmp_addr < s_addr->data_start_addr || tmp_addr > s_addr->data_end_addr) {
        //APP_MEM_LOG("oldest_index address error: %x.\n", tmp_addr);
        app_store_mem_error_handle();
        return false;
    }

    s_addr->tmp_addr = tmp_addr;

    return true;
}


static bool init_valid_addr(index_data_t *s_addr)
{
    uint32_t i;
    uint8_t result = 0;
    //bool sector1_valid = false, sector2_valid = false;
    index_content_t index[2];

    s_addr->addr_valid = false;

    for(i=0;i<((s_addr->index_end_addr - s_addr->index_start_addr)/sizeof(index_content_t));i++) {
        hal_store_read(s_addr->index_start_addr+(i*sizeof(index_content_t)), (uint8_t*)&index, sizeof(index));
        if(INDEX_HEADER == index[0].header && INDEX_HEADER != index[1].header) {
            if(index[0].crc16 != ls_ble_crc16_calc((uint8_t*)&index[0].latest_addr, 8, CRC_INIT_VALUE)) {
                APP_MEM_LOG("init_valid_addr crc err.\n");
                return false;
            }
            if(i == (((s_addr->index_end_addr - s_addr->index_start_addr)/sizeof(index_content_t)) -1)) {
                result += update_index_addr(s_addr->index_start_addr, s_addr);
            }
            else {
                result += update_index_addr(s_addr->index_start_addr+ ((i+1)*sizeof(index_content_t)), s_addr);
            }
            result += update_latest_data_addr(index[0].latest_addr, s_addr);
            result += update_oldest_data_addr(index[0].oldest_addr, s_addr, false);
            if(result < 3) {
                APP_MEM_LOG("Invalid index: %d.\n", i);
                return false;
            }
            s_addr->addr_valid = true;
            return true;
        }
    }

    if(i >= (s_addr->index_end_addr - s_addr->index_start_addr)/sizeof(index_content_t)) { //Fresh flash
        update_index_addr(s_addr->index_start_addr, s_addr);
        update_latest_data_addr(s_addr->data_start_addr, s_addr);
        update_oldest_data_addr(s_addr->data_start_addr, s_addr, false);
        hal_store_erase_sector(s_addr->data_start_addr);
        s_addr->addr_valid = true;
        APP_MEM_LOG("Fresh flash!\n");
    }

    //if(!s_addr->addr_valid) {
        //APP_MEM_LOG("index_addr is invalid.\n");
    //}
    //APP_MEM_LOG("i:%d \n", i);
    //APP_MEM_LOG("latest: %x, oldest: %x, locate: %x\n", s_addr->latest_addr, s_addr->oldest_addr, s_addr->index_addr);
    return true;
}


static bool check_data_index_valid(index_data_t *s_addr)
{
    index_content_t index;
    hal_store_read(s_addr->index_addr, (uint8_t*)&index, sizeof(index));
    if(INDEX_HEADER != index.header) {
        APP_MEM_LOG("Invalid header.\n");
        return false;
    }
    
    if(index.crc16 != ls_ble_crc16_calc((uint8_t*)&index.latest_addr, 8, CRC_INIT_VALUE)) {
        APP_MEM_LOG("check_data_index_valid fail.\n");
        return false;
    }
    
    return true;
}


static bool save_data_index(index_data_t *s_addr)
{
    uint8_t i = 0;
    bool check_valid = false;
    index_content_t index;
    uint32_t temp_idx = 0, border_addr = 0;

    if(!s_addr->addr_valid)
        return false;

    for(i=0;i<CHECK_VALID_MAX_TIMES;i++) {
        //Force to check and erase next sector.
        border_addr = ((s_addr->index_addr/FLASH_SECTOR_SIZE) + 1)*FLASH_SECTOR_SIZE;
        if((s_addr->index_addr < s_addr->index_end_addr)\
            && (s_addr->index_addr + 2*sizeof(index) >= s_addr->index_end_addr))
        {
            hal_store_erase_sector(s_addr->index_start_addr);
        }
        else if((s_addr->index_addr < border_addr) \
            && ((s_addr->index_addr + sizeof(index)) >= border_addr))
        {
            hal_store_erase_sector((((s_addr->index_addr/FLASH_SECTOR_SIZE) + 1)*FLASH_SECTOR_SIZE));
        }

        //check_nor_data_whole_size(oldest_data_index, latest_data_index);
        index.header = INDEX_HEADER;
        index.latest_addr = s_addr->latest_addr;
        index.oldest_addr = s_addr->oldest_addr;
        index.crc16 = ls_ble_crc16_calc((uint8_t*)&index.latest_addr, 8, CRC_INIT_VALUE);
        //APP_MEM_LOG("update latest: %x, oldest: %x\n", latest_data_index, oldest_data_index);
        hal_store_write(s_addr->index_addr, (uint8_t*)&index, sizeof(index));

        temp_idx = s_addr->index_addr + sizeof(index);
        if((temp_idx + sizeof(index)) > s_addr->index_end_addr) {
            temp_idx = s_addr->index_start_addr;
            //APP_MEM_LOG("Next locate loop.\n");
        }
        
        check_valid = check_data_index_valid(s_addr); //Must before update_index_addr
        update_index_addr(temp_idx, s_addr);
        if(true == check_valid) {
            break;
        }
        //if crc error, write in next area.
    }
    
    if(i >= 3) {
        APP_MEM_LOG("Three times data index not valid.\n");
        app_store_mem_error_handle();
        return false;
    }

    APP_MEM_LOG("latest: %x, oldest: %x, index: %x.\n", s_addr->latest_addr, s_addr->oldest_addr, s_addr->index_addr);
    return true;
}


static bool check_pack_and_save_data_valid(index_data_t *s_addr)
{
    uint8_t buf[32];
    uint16_t read_crc16 = 0;
    uint16_t calc_crc16 = CRC_INIT_VALUE;
    uint32_t len = 0;
    uint32_t addr_offset = 0;
    uint32_t left_size = s_addr->data_size;
    
    while(left_size > 0) {
        if(left_size >= sizeof(buf)) {
            len = sizeof(buf);
        }
        else {
            len = left_size;
        }
        addr_offset = s_addr->data_size - left_size;
        hal_store_read((s_addr->latest_addr + addr_offset), buf, len);
        if(left_size == s_addr->data_size) {
            if(DATA_SAVE_HEAD1 != buf[0]) {
                return false;
            }
            memcpy((uint8_t*)&read_crc16, &buf[1], sizeof(read_crc16));
            calc_crc16 = ls_ble_crc16_calc(&buf[sizeof(save_common_head_t)], (len-sizeof(save_common_head_t)), calc_crc16);
        }
        else {
            calc_crc16 = ls_ble_crc16_calc(buf, len, calc_crc16);
        }
        left_size -= len;
    }
    
    if(read_crc16 != calc_crc16) {
        APP_MEM_LOG("check_pack_and_save_data_valid fail: %x, %x.\n", read_crc16, calc_crc16);
        return false;
    }

    return true;
}


void pack_and_save_data(index_data_t *s_addr, uint8_t* data, uint16_t size)
{
    uint8_t i = 0;
    uint32_t address = 0, temp_idx = 0;
    bool check_valid = false;

    if(!s_addr->addr_valid)
        return;

    for(i=0;i<CHECK_VALID_MAX_TIMES;i++) {
        //Check and force to erase nouse area.
        //We consider the max size.
        //Maybe ignore some last area, so calculate with 2*sizeof(Sports_t).
        if((s_addr->latest_addr <= s_addr->data_end_addr) \
            && ((s_addr->latest_addr + 2*size) >= s_addr->data_end_addr))
        {
            hal_store_erase_sector(s_addr->data_start_addr);
        }
        else if((s_addr->latest_addr % FLASH_SECTOR_SIZE >= (FLASH_SECTOR_SIZE - size)) \
            && (((s_addr->latest_addr + size)%FLASH_SECTOR_SIZE) <= size))
        {
            address = (s_addr->latest_addr/FLASH_SECTOR_SIZE)*FLASH_SECTOR_SIZE + FLASH_SECTOR_SIZE;
            hal_store_erase_sector(address);
        }
        
        data[0] = DATA_SAVE_HEAD1;
        
        uint16_t calc_crc16 = ls_ble_crc16_calc(&data[sizeof(save_common_head_t)], (size - sizeof(save_common_head_t)), CRC_INIT_VALUE);
        data[1] = (calc_crc16 & 0xff);
        data[2] = (calc_crc16 >> 8) & 0xff;

        hal_store_write(s_addr->latest_addr, (uint8_t*)&data[0], size);
        temp_idx = s_addr->latest_addr + size;
        //We consider the max size, ignore the last not enough area.
        if((temp_idx + size) > s_addr->data_end_addr)
            temp_idx = s_addr->data_start_addr;
        
        check_valid = check_pack_and_save_data_valid(s_addr);   //Must before update_latest_data_addr
        
        if(false == update_latest_data_addr(temp_idx, s_addr)) {
            return;
        }
        if(false == update_oldest_data_addr(s_addr->oldest_addr, s_addr, check_valid)) {    //if valid we check max size
            return;
        }
        
        save_data_index(s_addr);
        
        if(true == check_valid) {
            break;
        }
        //if crc error, write in next area.
    }

    if(i >= CHECK_VALID_MAX_TIMES) {
        APP_MEM_LOG("Three times packet index not valid.\n");
        app_store_mem_error_handle();
    }
}


bool is_exist_unsent_data(index_data_t s_addr)
{
    //APP_MEM_LOG("Oldest: %x, Latest: %x\n", oldest_data_index, latest_data_index);
    if(s_addr.oldest_addr == s_addr.latest_addr)
        return false;
    else
        return true;
}

//TODO: The device may power down suddenly, and the packet is not valid.
//		So we need to abandon the packet if its crc verification can not pass.
static bool read_oldest_data(index_data_t *s_addr, uint8_t* r_data, uint16_t size, bool set_tmp_addr)
{
    save_common_head_t head;
    uint32_t temp_idx = 0;
    uint8_t i = 0, j = 0;
    bool valid = false;

    if(!s_addr->addr_valid)
        return false;

    if(true == set_tmp_addr) {
        s_addr->tmp_addr = s_addr->oldest_addr;
    }

    for(j=0;i<CHECK_VALID_MAX_TIMES;j++) {
        for(i=0;i<2;i++) {
            hal_store_read(s_addr->tmp_addr, r_data, size);
            memcpy((uint8_t*)&head, r_data, sizeof(head));
            uint16_t calc_crc16 = ls_ble_crc16_calc(&r_data[sizeof(save_common_head_t)], (size - sizeof(save_common_head_t)), CRC_INIT_VALUE);
            if(DATA_SAVE_HEAD1 != head.byte1 || head.crc16 != calc_crc16) {
                APP_MEM_LOG("byte1: %x\n", head.byte1);
                APP_MEM_LOG("crc16 err: %x, %x\n", head.crc16, calc_crc16);
            }
            else {
                valid = true;
                break;
            }
        }
        
        //We consider the max size, ignore the last not enough area.
        temp_idx = s_addr->tmp_addr + size;
        if((temp_idx + size) > s_addr->data_end_addr)
            temp_idx = s_addr->data_start_addr;
        if(false == update_tmp_data_addr(temp_idx, s_addr))
            return false;
        
        //If read data is not valid, we skip to next area.
        if(valid) {
            return true;
        }
    }

    //TODO:
    return false;
}


bool read_latest_data(index_data_t *s_addr, uint8_t* r_data, uint16_t size)
{
    save_common_head_t head;
    uint32_t addr = s_addr->latest_addr - s_addr->data_size;

    if(!s_addr->addr_valid)
        return false;

    //STORE_LOG("read addr: %x.\n", s_addr->oldest_addr);
    hal_store_read(addr, r_data, size);
    memcpy((uint8_t*)&head, r_data, sizeof(head));
    uint16_t calc_crc16 = ls_ble_crc16_calc(&r_data[sizeof(save_common_head_t)], (size - sizeof(save_common_head_t)), CRC_INIT_VALUE);
    if(DATA_SAVE_HEAD1 != head.byte1 || head.crc16 != calc_crc16) {
        APP_MEM_LOG("byte1 err: %x, crc: %x, %x\n", head.byte1, head.crc16, calc_crc16);
        app_store_mem_error_handle();
        return false;
    }

    return true;
}


static bool abandon_data_have_sent(index_data_t *s_addr)
{
    if(s_addr->oldest_addr == s_addr->latest_addr)
        return true;

    s_addr->oldest_addr = s_addr->tmp_addr;

    save_data_index(s_addr);

    return true;
}


static uint32_t sizeof_data_need_to_be_sent(index_data_t *s_addr)
{
    uint32_t size = 0;

    if(!s_addr->addr_valid)
        return 0;

    if(s_addr->latest_addr >= s_addr->oldest_addr)
        size = (s_addr->latest_addr - s_addr->oldest_addr);
    else {
        uint32_t rest = (s_addr->data_end_addr - s_addr->data_start_addr) % s_addr->data_size;
        size = (s_addr->latest_addr - s_addr->data_start_addr) + (s_addr->data_end_addr - s_addr->oldest_addr - rest);
    }

    return size;
}


void app_mem_latest_skip_ret_read(uint8_t* pData, uint16_t size)
{
    save_skip_packet_t skip_pkt;

    if(size < sizeof(skip_pkt.skip))
        return;

    if(read_latest_data(&skip_index, (uint8_t*)&skip_pkt, sizeof(skip_pkt))) {
        memcpy(pData, (uint8_t*)&skip_pkt.skip, sizeof(skip_pkt.skip));
    }
}


void app_mem_unsent_skip_data_read(uint8_t* pData, uint16_t size)
{
    save_skip_packet_t skip_pkt;

    if(sizeof_data_need_to_be_sent(&skip_index) > 0) {
        if(read_oldest_data(&skip_index, (uint8_t*)&skip_pkt, sizeof(skip_pkt), true)) {
            memcpy(pData, (uint8_t*)&skip_pkt.skip, sizeof(skip_pkt.skip));
        }
    }
}


void app_mem_sent_data_abandon(void)
{
    abandon_data_have_sent(&skip_index);
}


uint32_t app_mem_unsent_data_size_get(void)
{
    return sizeof_data_need_to_be_sent(&skip_index);
}


void app_mem_skip_data_save(void)
{
    save_skip_packet_t save_skip_pkt;

#if 1
    skip_packet_t *g_skip = &g_app_data.tmp.skip;

    APP_MEM_LOG("utc: %d.\n", g_skip->start_utc);
    APP_MEM_LOG("mode: %d.\n", g_skip->mode);
    APP_MEM_LOG("secs: %d.\n", g_skip->total_secs);
    APP_MEM_LOG("cnt: %d.\n", g_skip->total_cnts);
    APP_MEM_LOG("freq avg: %d.\n", g_skip->freq_avg);
    APP_MEM_LOG("freq max: %d.\n", g_skip->freq_max);
    APP_MEM_LOG("conti max: %d.\n", g_skip->consecutive_skip_max_num);
    for(uint8_t i=0;i<=g_skip->trip_num;i++) {
        APP_MEM_LOG("c_sec: %d.\n", g_skip->group[i].skip_sec);
        APP_MEM_LOG("c_cnt: %d.\n", g_skip->group[i].skip_cnt);
    }

    memcpy((uint8_t*)&save_skip_pkt.skip, (uint8_t*)g_skip, sizeof(skip_packet_t));
    pack_and_save_data(&skip_index, (uint8_t*)&save_skip_pkt, sizeof(save_skip_pkt));
#else
    skip_packet_t g_skip;
    static uint16_t offset = 1;
    g_skip.start_utc = 1608343471 + offset;
    g_skip.mode = 0;
    g_skip.setting = 80;
    g_skip.total_secs = 0;
    g_skip.total_cnts = 0;
    g_skip.freq_avg = 100;
    g_skip.freq_max = 123;
    g_skip.consecutive_skip_max_num = 111;
    g_skip.trip_num = 49;
    for(uint8_t i=0;i<=g_skip.trip_num;i++) {
        g_skip.group[i].skip_sec = offset + i;
        g_skip.group[i].skip_cnt = offset + i;
        g_skip.total_secs += g_skip.group[i].skip_sec;
        g_skip.total_cnts += g_skip.group[i].skip_cnt;
    }
    offset++;

    memcpy((uint8_t*)&save_skip_pkt.skip, (uint8_t*)&g_skip, sizeof(g_skip));
    pack_and_save_data(&skip_index, (uint8_t*)&save_skip_pkt, sizeof(save_skip_pkt));
#endif
}


void app_mem_data_init(void)
{
    if(false == init_valid_addr(&skip_index)) {
        for(int i=0;i<((SKIP_DATA_SAVED_END_ADDR - SF_MEM_DATA_ADDR)/FLASH_SECTOR_SIZE);i++) {
            hal_store_erase_sector(SF_MEM_DATA_ADDR + i*FLASH_SECTOR_SIZE);
            WDT_FEED();
        }
        init_valid_addr(&skip_index);
    }
}


void app_store_mem_data_revert(void)
{
    uint32_t i;

    //Clear sport cache data
    for(i=0;i<((SKIP_DATA_SAVED_END_ADDR - TEMP_DATA_RST_ADDR)/FLASH_SECTOR_SIZE);i++) {
        hal_store_erase_sector(TEMP_DATA_RST_ADDR + i*FLASH_SECTOR_SIZE);
        WDT_FEED();
    }

    app_mem_data_init();
}


void app_mem_data_clear_all(void)
{
    uint32_t i;

    //Clear sport cache data
    for(i=0;i<((SKIP_DATA_SAVED_END_ADDR - SF_MEM_DATA_ADDR)/FLASH_SECTOR_SIZE);i++) {
        hal_store_erase_sector(SF_MEM_DATA_ADDR + i*FLASH_SECTOR_SIZE);
        WDT_FEED();
    }

    app_mem_data_init();
}


#if 0
#include "app_time.h"
void app_mem_store_test(void)
{
    //skip_packet_t skip_pkt;
    static uint16_t offset = 1;
    save_skip_packet_t save_skip_pkt;

    //app_mem_data_clear_all();

    for(uint16_t i=0;i<100;i++) {
        skip_packet_t g_skip;
        g_skip.start_utc = app_time_universal_utc_get() + offset;
        g_skip.mode = 0;
        g_skip.setting = 80;
        g_skip.total_secs = 0;
        g_skip.total_cnts = 0;
        g_skip.freq_avg = 100;
        g_skip.freq_max = 123;
        g_skip.consecutive_skip_max_num = 111;
        g_skip.trip_num = 0;
        for(uint8_t i=0;i<=g_skip.trip_num;i++) {
            g_skip.group[i].skip_sec = i;
            g_skip.group[i].skip_cnt = i;
            g_skip.total_secs += g_skip.group[i].skip_sec;
            g_skip.total_cnts += g_skip.group[i].skip_cnt;
        }
        g_skip.group[49].skip_sec = offset;
        g_skip.group[49].skip_cnt = offset;
        g_skip.total_secs += g_skip.group[49].skip_sec;
        g_skip.total_cnts += g_skip.group[49].skip_cnt;
        g_skip.trip_num = 0;
        offset++;

        memcpy((uint8_t*)&save_skip_pkt.skip, (uint8_t*)&g_skip, sizeof(g_skip));
        pack_and_save_data(&skip_index, (uint8_t*)&save_skip_pkt, sizeof(save_skip_pkt));
    }

    /*uint32_t left_size = app_mem_unsent_data_size_get();
    APP_MEM_LOG("left size1: %d.\n", left_size);
    while(app_mem_unsent_data_size_get()) {
        app_mem_unsent_skip_data_read((uint8_t*)&skip_pkt, sizeof(skip_pkt));
        abandon_data_have_sent(&skip_index);
        APP_MEM_LOG("utc1: %d.\n", skip_pkt.start_utc);
        APP_MEM_LOG("mode1: %d.\n", skip_pkt.mode);
        APP_MEM_LOG("secs1: %d.\n", skip_pkt.used_sec);
        APP_MEM_LOG("cnt1: %d.\n", skip_pkt.jump_cnt);
        APP_MEM_LOG("freq avg1: %d.\n", skip_pkt.freq_avg);
        APP_MEM_LOG("freq max1: %d.\n", skip_pkt.freq_max);
        for(uint8_t i=0;i<skip_pkt.conti_valid_num;i++) {
            APP_MEM_LOG("c_sec1: %d.\n", skip_pkt.conti[i].secs);
            APP_MEM_LOG("c_cnt1: %d.\n", skip_pkt.conti[i].jump_cnt);
        }
        wdt_feed(0x3fff);
    }*/

    /*left_size = app_mem_unsent_data_size_get();
    APP_MEM_LOG("left size2: %d.\n", left_size);

    for(uint16_t i=0;i<200;i++) {
        app_mem_skip_data_save();
    }

    left_size = app_mem_unsent_data_size_get();
    APP_MEM_LOG("left size3: %d.\n", left_size);

    while(app_mem_unsent_data_size_get()) {
        app_mem_unsent_skip_data_read((uint8_t*)&skip_pkt, sizeof(skip_pkt));
        abandon_data_have_sent(&skip_index);
        APP_MEM_LOG("utc1: %d.\n", skip_pkt.start_utc);
        APP_MEM_LOG("mode1: %d.\n", skip_pkt.mode);
        APP_MEM_LOG("secs1: %d.\n", skip_pkt.used_sec);
        APP_MEM_LOG("cnt1: %d.\n", skip_pkt.jump_cnt);
        APP_MEM_LOG("freq avg1: %d.\n", skip_pkt.freq_avg);
        APP_MEM_LOG("freq max1: %d.\n", skip_pkt.freq_max);
        for(uint8_t i=0;i<skip_pkt.conti_valid_num;i++) {
            APP_MEM_LOG("c_sec1: %d.\n", skip_pkt.conti[i].secs);
            APP_MEM_LOG("c_cnt1: %d.\n", skip_pkt.conti[i].jump_cnt);
        }
    }*/
}
#endif
